interface dataSourceType {
  [propName: string]: any;
}
let reg_rulers: dataSourceType = {
  email: /^[a-zA-Z0-9][a-zA-Z0-9 . _-]+(@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+)$/,
  lowerCase: /^[A-Z]+$/,
  english: /^[A-Za-z]+$/,
  chinese: /^[\u4e00-\u9fa5]+$/,
  noChinese: /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/g,
  noChinese2: /^[\n!#%+-=/\][{}|A-Za-z0-9]+$/,
  cnEnNum: /^[\u4e00-\u9fa5|A-Za-z0-9]+$/,
  path: /^[-|_|/|A-Za-z0-9]+$/,
  cnEnNumPath: /^[/|\u4e00-\u9fa5|A-Za-z0-9]+$/,
  cnEnNumSymbol: /^[、,，;；。'"|\u4e00-\u9fa5|A-Za-z0-9]+$/,
  enNumLine: /^[_|A-Za-z0-9]+$/,
  enNum: /^[A-Za-z0-9]+$/,
  haveCnEnNum: /^(?=.*[a-zA-Z]+)(?=.*[0-9]+)[a-zA-Z0-9]+$/,
  haveNum: /^(?=.*?[0-9])(?=.*?[a-zA-Z])[0-9a-zA-Z]+$/,
  haveEnNum: /^(?=.*[0-9].*)(?=.*[A-Z].*)(?=.*[a-z].*)[0-9a-zA-Z]+$/,
  haveEnNumSpe: /^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^(0-9a-zA-Z)]).{1,}$/,
  haveEnSpe: /^(?![A-Za-z0-9]+$)(?![a-z0-9\\W]+$)(?![A-Za-z\\W]+$)(?![A-Z0-9\\W]+$)[a-zA-Z0-9\\W]{1,}$/,
  mobile: /^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(16[2|6|7])|(18[0-9])|(17([0-1]|[3]|[5-8]))|(19[1|8|9]))\d{8}$/,
  phone: /^((\d{3,4}-\d{7,8})|(\d{7}-\d{1,12})|(\d{8}-\d{1,11})|(\d{11}-\d{1,8})|(\d{7,8})|(\d{11,20})|(\d{3}-\d{8}-\d{1,7})|(\d{3}-\d{7}-\d{1,8})|(\d{4}-\d{7}-\d{1,7})|(\d{4}-\d{8}-\d{1,6}))$/,
  phoneAll: /^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(16[2|6|7])|(18[0-9])|(17([0-1]|[3]|[5-8]))|(19[1|8|9]))\d{8}$|^((\d{3,4}-\d{7,8})|(\d{7}-\d{1,12})|(\d{8}-\d{1,11})|(\d{11}-\d{1,8})|(\d{7,8})|(\d{11,20})|(\d{3}-\d{8}-\d{1,7})|(\d{3}-\d{7}-\d{1,8})|(\d{4}-\d{7}-\d{1,7})|(\d{4}-\d{8}-\d{1,6}))$/,
  float: /^[0-9]+([.]{1}[0-9]+){0,1}$/,
  decimal: /^(([0-9]*)|(([0]\.\d{1,2}|[0-9]*\.\d{1,2})))$/,
  greaterNumber: /^[0-9]\d*$/,
  plusNumber: /^(0|[1-9][0-9]*)(\.\d+)?$/,
  moreThanZeroNumber: /^\+?[1-9]\d*$/,
  url: /^(?=^.{3,255}$)(http(s)?:\/\/)?(www\.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/\w+\.\w+)*$/,
  ip: /^(?=(\b|\D))(((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))(?=(\b|\D))*$/,
  identity: /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X|x)$/,
  postal: /^\d{6}$/,
}
export function conmmon(_rule: dataSourceType, value: string, callback: () => {}, type: string, msg: string = '', useValue: any) {
  if (_rule.required) {// 必填项验证非空并排除非必须项
    if (!useValue) { // 使用fullField校验
      if ((value === '' || value === null || value === undefined) && !_rule.fullField) {
        return Promise.reject(`此项必填`);
      } else {
        const reg = reg_rulers[type];
        return reg.test(value || _rule.fullField) ? Promise.resolve() : msg ? Promise.reject(`${msg}`) : Promise.reject(`${_rule.msg2}`);
      }
    } else {
      if (!value || value == undefined) {
        return Promise.reject(`${_rule.msg1}`);
      } else {
        const reg = reg_rulers[type];
        return reg.test(value || _rule.fullField) ? Promise.resolve() : msg ? Promise.reject(`${msg}`) : Promise.reject(`${_rule.msg2}`);
      }
    }
  } else {
    if (!useValue) {
      if ((value === '' || value === null || value === undefined) && !_rule.fullField) {
        return Promise.resolve();
      } else {
        const reg = reg_rulers[type];
        return reg.test(value || _rule.fullField) ? Promise.resolve() : msg ? Promise.reject(`${msg}`) : Promise.reject(`${_rule.msg2}`);
      }
    } else {
      if (!value || value == undefined) {
        return Promise.resolve();
      } else {
        const reg = reg_rulers[type];
        return reg.test(value || _rule.fullField) ? Promise.resolve() : msg ? Promise.reject(`${msg}`) : Promise.reject(`${_rule.msg2}`);
      }
    }
  }
}
export default { // 所有验证，支持两种error message，若有更多类型限制，可自行扩展

  // 邮箱验证, 
  email: (_rule: dataSourceType, value: string, callback: () => {}, type = 'email', msg: '邮箱格式不正确', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 小写字母
  lowerCase: (_rule: dataSourceType, value: string, callback: () => {}, type = 'lowerCase', msg = '请输入小写字母', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 大小写字母
  english: (_rule: dataSourceType, value: string, callback: () => {}, type = 'english', msg = '请输入大小写字母', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 只能输中文
  chinese: (_rule: dataSourceType, value: string, callback: () => {}, type = 'chinese', msg = '请输入中文', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 不能输中文
  noChinese: (_rule: dataSourceType, value: string, callback: () => {}, type = 'noChinese', msg = '不能输入中文', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 输入数字、大小写字母和特殊字符
  noChinese2: (_rule: dataSourceType, value: string, callback: () => {}, type = 'noChinese2', msg = '请输入数字、大小写字母和特殊字符', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 中文英文数字
  cnEnNum: (_rule: dataSourceType, value: string, callback: () => {}, type = 'cnEnNum', msg = '请输入数字、中文，字母', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 路径
  path: (_rule: dataSourceType, value: string, callback: () => {}, type = 'path', msg = '请输入英文、数字、划线、斜线', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 中文英文数字斜线
  cnEnNumPath: (_rule: dataSourceType, value: string, callback: () => {}, type = 'cnEnNumPath', msg = '请输入中文、大小写英文、数字/、斜线', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 中文英文数字 符号
  cnEnNumSymbol: (_rule: dataSourceType, value: string, callback: () => {}, type = 'cnEnNumSymbol', msg = '请输入中文、大小写英文、数字、中文标点符', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 英文数字下划线
  enNumLine: (_rule: dataSourceType, value: string, callback: () => {}, type = 'enNumLine', msg = '请输入英文、数字、下划线', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 英文数字
  enNum: (_rule: dataSourceType, value: string, callback: () => {}, type = 'enNum', msg = '请输入英文、数字', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 必须包含英文数字
  haveCnEnNum: (_rule: dataSourceType, value: string, callback: () => {}, type = 'haveCnEnNum', msg = '只能包含英文和数字', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 必须包含字母和数字
  haveNum: (_rule: dataSourceType, value: string, callback: () => {}, type = 'haveNum', msg = '必须包含字母和数字', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 必须包含大，小写字母和数字
  haveEnNum: (_rule: dataSourceType, value: string, callback: () => {}, type = 'haveEnNum', msg = '必须包含大，小写字母和数字', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 必须包含字母和数字,特殊字符
  haveEnNumSpe: (_rule: dataSourceType, value: string, callback: () => {}, type = 'haveEnNumSpe', msg = '必须包含字母和数字,特殊字符', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 必须包含大写字母、小写字母、数字、特殊字符
  haveEnSpe: (_rule: dataSourceType, value: string, callback: () => {}, type = 'haveEnSpe', msg = '必须包含大写字母、小写字母、数字、特殊字符', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 手机号
  mobile: (_rule: dataSourceType, value: string, callback: () => {}, type = 'mobile', msg = '请输入正确的手机号码', useValue: number = 0) => { // 手机号码验证
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 座机
  phone: (_rule: dataSourceType, value: string, callback: () => {}, type = 'phone', msg = '请输入正确的座机号码', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 手机或座机
  phoneAll: (_rule: dataSourceType, value: string, callback: () => {}, type = 'phoneAll', msg = '请输入正确的电话号码', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 小数
  float: (_rule: dataSourceType, value: string, callback: () => {}, type = 'float', msg = '请输入合法的数字', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 两位小数
  decimal: (_rule: dataSourceType, value: string, callback: () => {}, type = 'decimal', msg = '请输入最多两位小数', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 整数
  number: (_rule: dataSourceType, value: string, callback: () => {}, type = 'number', msg = '请输入合法的数字', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 大于0整数
  greaterNumber: (_rule: dataSourceType, value: string, callback: () => {}, type = 'greaterNumber', msg = '请输入大于0且合法的数字', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 正数
  plusNumber: (_rule: dataSourceType, value: string, callback: () => {}, type = 'plusNumber', msg = '请输入合法的数字', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 大于0的正数
  moreThanZeroNumber: (_rule: dataSourceType, value: string, callback: () => {}, type = 'moreThanZeroNumber', msg = '只能输入大于0的整数', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 网址
  url: (_rule: dataSourceType, value: string, callback: () => {}, type = 'url', msg = '请输入正确的网址', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // ip地址
  ip: (_rule: dataSourceType, value: string, callback: () => {}, type = 'ip', msg = '请输入正确的ip', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 身份证号
  identity: (_rule: dataSourceType, value: string, callback: () => {}, type = 'identity', msg = '请输入正确的身份证号', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  },
  // 邮政编码
  postal: (_rule: dataSourceType, value: string, callback: () => {}, type = 'postal', msg = '请输入正确的邮政编码', useValue: number = 0) => {
    return conmmon(_rule, value, callback, type, msg, useValue);
  }
} as any